1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::value::*;
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Dependency {
pub variance: Variance,
pub relationship: Relationship,
}
impl PartialOrd for Dependency {
#[inline]
fn partial_cmp(&self, other: &Dependency) -> Option<Ordering> {
self.const_cmp(*other)
}
}
impl Debug for Dependency {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
if *self == Dependency::CONTRADICTION {
write!(fmt, "!")
} else {
write!(fmt, "SymDep({:?}, {:?})", self.variance, self.relationship)
}
}
}
impl Dependency {
pub const USED: Dependency = Dependency::covar(Usage::USED);
pub const CONTRADICTION: Dependency = Dependency {
variance: Invariant,
relationship: Relationship::CN,
};
pub const NULL: Dependency = Dependency {
variance: Bivariant,
relationship: Relationship::TV,
};
#[inline]
pub const fn covar(usage: Usage) -> Dependency {
Dependency {
variance: Covariant,
relationship: Relationship::dependency(usage),
}
}
#[inline]
pub const fn const_cmp(self, other: Dependency) -> Option<Ordering> {
lattice_ord_opt(
other.variance.const_cmp(self.variance),
self.relationship.const_cmp(other.relationship),
)
}
#[inline]
pub fn flip(self) -> Dependency {
Dependency {
variance: self.variance.flip(),
relationship: self.relationship.flip(),
}
}
#[inline]
pub fn of(self, symbol: &SymbolId) -> Dependency {
Dependency {
variance: self.variance.of(symbol),
relationship: self.relationship.of(symbol),
}
}
#[inline]
pub fn join(self, other: Dependency) -> Dependency {
Dependency {
variance: self.variance.join(other.variance),
relationship: self.relationship.join(other.relationship),
}
}
#[inline]
pub fn meet(self, other: Dependency) -> Dependency {
Dependency {
variance: self.variance.meet(other.variance),
relationship: self.relationship.meet(other.relationship),
}
}
#[inline]
pub fn iter_all() -> impl Iterator<Item = Dependency> {
RELATIONSHIPS
.iter()
.copied()
.map(|relationship| {
VARIANCES.iter().copied().map(move |variance| Dependency {
variance,
relationship,
})
})
.flatten()
}
}